package com.jic.market.impl.rest.promotion;

import com.alibaba.excel.util.StringUtils;
import com.alibaba.fastjson.JSONObject;
import com.google.common.base.Splitter;
import com.jic.common.base.vo.PageResult;
import com.jic.common.base.vo.RestResult;
import com.jic.market.common.enums.DeleteFlagEnum;
import com.jic.market.common.exception.MarketErrorCodeEnum;
import com.jic.market.common.exception.MarketException;
import com.jic.market.entity.PromotionEntity;
import com.jic.market.entity.PromotionMemberGrade;
import com.jic.market.entity.activity.ActivityPriority;
import com.jic.market.enums.PromotionTypeEnum;
import com.jic.market.impl.rest.promotion.promotionInfoHandler.BaseInfoHandler;
import com.jic.market.impl.rest.promotion.promotionInfoHandler.BaseInfoHandlerFactory;
import com.jic.market.mapper.PromotionEntityMapper;
import com.jic.market.mapper.PromotionMemberGradeMapper;
import com.jic.market.mapper.base.BaseActivityMapper;
import com.jic.market.request.CouponConfigQueryRequest;
import com.jic.market.request.PromotionPolymericRequest;
import com.jic.market.request.rest.promotion.PromotionInfoRestRequest;
import com.jic.market.response.CouponConfigQueryResponse;
import com.jic.market.response.PromotionPolymericProductResponse;
import com.jic.market.response.PromotionPolymericResponse;
import com.jic.market.response.rest.promotion.PromotionDetailRestResponse;
import com.jic.market.response.rest.promotion.PromotionGoodsSpuRestResponse;
import com.jic.market.response.rest.promotion.PromotionInfoRestResponse;
import com.jic.market.service.PromotionMemberGradeService;
import com.jic.market.service.activity.ActivityPriorityService;
import com.jic.market.service.rest.promotion.PromotionRestService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.function.Predicate;
import java.util.stream.Collectors;

/**
 * description: PromotionRestServiceImpl
 * date: 2020/4/8 11:16
 * author: wangys
 * version: 1.0
 */
@Service
@Slf4j
public class PromotionRestServiceImpl implements PromotionRestService {

    @Autowired
    BaseInfoHandlerFactory baseInfoHandlerFactory;

    @Autowired
    ActivityPriorityService activityPriorityService;
    @Autowired
    private PromotionMemberGradeService promotionMemberGradeService;

    @Autowired
    private PromotionMemberGradeMapper promotionMemberGradeMapper;

    @Autowired
    private PromotionEntityMapper promotionEntityMapper;

    @Autowired
    private BaseActivityMapper baseActivityMapper;

    final static Predicate<PromotionEntity> ING_CHECK = (x)->{
        Long currentTimeMillis = System.currentTimeMillis();
        return x.getStatus() == 11 && currentTimeMillis >= x.getStartTime().getTime() && currentTimeMillis <= x.getEndTime().getTime();
    };

    /**
     * 根据spuId查询参与的活动列表
     * TODO 最优选取一个
     * @param request
     * @return
     */
    @Override
    public PromotionInfoRestResponse getPromotinInfo(PromotionInfoRestRequest request) {
        log.info("getPromotinInfo param = {}", JSONObject.toJSONString(request));
//        if(StringUtils.isEmpty(request.getThirdProductCode())){
//            throw new MarketException(MarketErrorCodeEnum.PARAM_ERROR, "商品编码非空");
//        }
        if (request.getMpId() == null){
            throw new MarketException(MarketErrorCodeEnum.PARAM_ERROR, "商品Id非空");
        }
        PromotionInfoRestResponse promotionInfoRestResponse = new PromotionInfoRestResponse();
        List<PromotionDetailRestResponse> promotions = new ArrayList<>();
        List<PromotionEntity> promotionEntities = getPromotionEntities(request);
        if(CollectionUtils.isNotEmpty(promotionEntities)){
            promotionEntities.forEach(p->{
                request.setPromotionCode(p.getPromotionCode());
                request.setFrontPromotionType(p.getFrontPromType());
                // 过滤等级
                Boolean gradeFlag = Boolean.FALSE;
//                if(org.apache.commons.lang.StringUtils.isNotBlank(request.getThirdUserId()) && org.apache.commons.lang.StringUtils.isNotBlank(request.getChannelCode())){
//                    PromotionMemberGrade promotionMemberGradeQ = new PromotionMemberGrade();
//                    promotionMemberGradeQ.setPromotionCode(p.getPromotionCode());
//                    promotionMemberGradeQ.setDeleteFlag(false);
//                    List<PromotionMemberGrade> promotionMemberGradeList = promotionMemberGradeMapper.query(promotionMemberGradeQ);
//                    gradeFlag = promotionMemberGradeService.checkPromotion(request.getThirdUserId(), request.getChannelCode(), p.getChannelCodes(), promotionMemberGradeList);
//                }
//                if(gradeFlag){
//                }
                promotions.add(promotionDetail(request));
            });
        }
        promotionInfoRestResponse.setPromotions(promotions);
        promotionInfoRestResponse.setThirdProductCode(request.getThirdProductCode());
        log.info("getPromotinInfo param = {}, result = {}", JSONObject.toJSONString(request), JSONObject.toJSONString(promotionInfoRestResponse));
        return promotionInfoRestResponse;
    }

    /**
     * 获取活动详情
     * @param request
     * @return
     */
    @Override
    public PromotionDetailRestResponse promotionDetail(PromotionInfoRestRequest request) {
        log.info("promotionDetail param = {}", JSONObject.toJSONString(request));
        if(StringUtils.isEmpty(request.getPromotionCode())){
            throw new MarketException(MarketErrorCodeEnum.PARAM_ERROR, "活动编码非空");
        }
        if(request.getFrontPromotionType() == null){
            PromotionEntity promotionEntity = promotionDetailByPromotionCode(request.getPromotionCode());
            request.setFrontPromotionType(promotionEntity.getFrontPromType());
        }
        PromotionDetailRestResponse restResponse = null;
        BaseInfoHandler promotionHandler = baseInfoHandlerFactory.getPromotionHandlerByFrontType(request.getFrontPromotionType());
        if(promotionHandler == null){
            log.error("promotionDetail getPromotionHandlerByFrontType error promotionCode = {}, frontPromotionType = {}", request.getPromotionCode(), request.getFrontPromotionType());
            return restResponse;
        }
        restResponse = promotionHandler.promotionDetail(request);
        log.info("promotionDetail param = {}, handler = {}, result = {}", JSONObject.toJSONString(request), promotionHandler.handlerCode(), JSONObject.toJSONString(restResponse));
        return restResponse;
    }

    /**
     * 根据优先级获取活动基本信息-排除规则信息和赠品信息
     * @param request
     * @return
     */
    @Override
    public PromotionEntity promotionDetailPriority(PromotionInfoRestRequest request){
        List<PromotionEntity> collect = getPromotionEntities(request);
        return processPriority(collect);
    }

    /**
     * 获取商品参与的活动列表
     * @param request
     * @return
     */
    @Override
    public List<PromotionEntity> getPromotionEntities(PromotionInfoRestRequest request) {
        log.info("promotionDetailPriority param = {}", JSONObject.toJSONString(request));
        List<PromotionEntity> promotions = new ArrayList<>();
        List<BaseInfoHandler> baseInfoHandlers = baseInfoHandlerFactory.getBaseInfoHandlers();
        baseInfoHandlers.forEach(handler->{
            List<PromotionEntity> promotionEntities = handler.promotionBaseDetail(request);
            if(CollectionUtils.isNotEmpty(promotionEntities)){
                promotions.addAll(promotionEntities);
            }
        });
//        List<PromotionEntity> collect = null;
//        if(request.getAdminOperate() != null && CollectionUtils.isNotEmpty(request.getAdminOperate().getDeptIds())){
//            Long childId = request.getAdminOperate().getChildId();
//            List<Long> deptIds = request.getAdminOperate().getDeptIds();
//            collect = promotions.stream().filter(p -> {
//                List<String> channelCodes = Splitter.on(",").splitToList(p.getChannelCodes());
//                Boolean flag = deptIds.contains(p.getDeptId()) || channelCodes.contains(childId + "");
//                log.info("promotionDetailPriority promotionCode = {}, childId = {}, deptIds = {}, channelCodes = {}, flag = {}", p.getPromotionCode(), childId, deptIds, p.getChannelCodes(), flag);
//                return flag;
//            }).collect(Collectors.toList());
//        }else{
//            collect = promotions;
//        }
        log.info("promotionDetailPriority param = {}, result = {}", JSONObject.toJSONString(request), JSONObject.toJSONString(promotions));
        return promotions;
    }

    /**
     *
     * @param promotionCode
     * @return
     */
    @Override
    public PromotionEntity promotionDetailByPromotionCode(String promotionCode) {
        log.info("promotionDetailByPromotionCode promotionCode = {}", promotionCode);
        PromotionEntity promotionEntity = null;
        List<BaseInfoHandler> baseInfoHandlers = baseInfoHandlerFactory.getBaseInfoHandlers();
        for (BaseInfoHandler baseInfoHandler : baseInfoHandlers) {
            promotionEntity = baseInfoHandler.getPromotionDetailByPromotionCode(promotionCode);
            if(promotionEntity != null){
                //判断活动是否结束
                if(!ING_CHECK.test(promotionEntity)){
                    throw new MarketException(MarketErrorCodeEnum.PROMOTION_ING_CHECK_ERROR);
                }
                break;
            }
        }
        if(promotionEntity == null){
            log.error("promotionDetailByPromotionCode 无此活动 promotionCode = {}", promotionCode);
            throw new MarketException(MarketErrorCodeEnum.PROMOTION_CHECK_ERROR);
        }
        log.info("promotionDetailByPromotionCode promotionCode = {}, result = {}", promotionCode, JSONObject.toJSONString(promotionEntity));
        return promotionEntity;
    }

    @Override
    public PageResult<PromotionGoodsSpuRestResponse> getGoodsByPromotionCode(PromotionInfoRestRequest request) {
        log.info("getGoodsByPromotionCode param = {}", JSONObject.toJSONString(request));
        if(StringUtils.isEmpty(request.getPromotionCode())){
            throw new MarketException(MarketErrorCodeEnum.PARAM_ERROR, "活动编码非空");
        }
        //查询出对应的活动
        PromotionEntity promotionEntity = promotionDetailByPromotionCode(request.getPromotionCode());
        BaseInfoHandler promotionHandler = baseInfoHandlerFactory.getPromotionHandlerByFrontType(promotionEntity.getFrontPromType());
        if(promotionHandler == null){
            log.error("getGoodsByPromotionCode error handler is null promotionCode = {}", request.getPromotionCode());
            return null;
        }
        log.info("getGoodsByPromotionCode entry process param = {}, handler = {}", JSONObject.toJSONString(request), promotionHandler.handlerCode());
        PageResult<PromotionGoodsSpuRestResponse> goodsByPromotionCode = promotionHandler.getGoodsByPromotionCode(request, promotionEntity.getId());
        log.info("getGoodsByPromotionCode param = {}, result = {}", JSONObject.toJSONString(request), JSONObject.toJSONString(goodsByPromotionCode));
        return goodsByPromotionCode;
    }

    @Override
    public List<PromotionInfoRestResponse> getPromotinInfos(PromotionInfoRestRequest request) {
        log.info("getPromotinInfos param = {}", JSONObject.toJSONString(request));
        List<String> thirdProductCodes = request.getThirdProductCodes();
        List<PromotionInfoRestResponse> collect = thirdProductCodes.stream().map(t -> {
            request.setThirdProductCode(t);
            return getPromotinInfo(request);
        }).collect(Collectors.toList());
        log.info("getPromotinInfos param = {}, result = {}", JSONObject.toJSONString(request), JSONObject.toJSONString(collect));
        return collect;
    }

    @Override
    public RestResult<PromotionPolymericResponse> queryPromotionPolymericInfo(PromotionPolymericRequest request) {
        if (org.apache.commons.lang3.StringUtils.isEmpty(request.getPromotionId()) || request.getPromotionType() == null){
            return RestResult.error("9999","活动id或活动类型为空");
        }
        PromotionPolymericResponse promotionPolymericResponse = new PromotionPolymericResponse();
        if (request.getPromotionType().equals(PromotionTypeEnum.Coupon.getCode())){
            // 优惠券
            CouponConfigQueryRequest couponConfigQueryRequest = new CouponConfigQueryRequest(){{
                setPromotionId(request.getPromotionId());
            }};
            CouponConfigQueryResponse couponConfigQueryResponse = baseActivityMapper.getCouponByPromotionId(couponConfigQueryRequest);
            if (couponConfigQueryResponse == null){
                log.error("查询活动为空，promotionId:{}",request.getPromotionId());
                return RestResult.error("9999","查询活动为空");
            }
            promotionPolymericResponse.setPromId(couponConfigQueryResponse.getPromotionId());
            promotionPolymericResponse.setPromName(couponConfigQueryResponse.getPromName());
            promotionPolymericResponse.setPromType(Integer.valueOf(couponConfigQueryResponse.getPromType()));
            promotionPolymericResponse.setDescription(couponConfigQueryResponse.getDescription());
        }else {
            // 其他活动
            promotionPolymericResponse = promotionEntityMapper.queryPromotionPolyInfo(request);
            if (promotionPolymericResponse == null){
                log.error("查询活动为空，promotionId:{}",request.getPromotionId());
                return RestResult.error("9999","查询活动为空");
            }
        }
        return RestResult.success(promotionPolymericResponse);
    }

    /**
     * 获取活动优先级
     * @param promotions
     * @return
     */
    private PromotionEntity processPriority(List<PromotionEntity> promotions){
        log.info("processPriority param = {}", JSONObject.toJSONString(promotions));
        PromotionEntity promotionEntity = null;
        if(CollectionUtils.isEmpty(promotions)){
            return promotionEntity;
        }
        Map<Integer, PromotionEntity> promotionEntityMap = promotions.stream()
                .sorted(Comparator.comparing(PromotionEntity::getCreateTime).reversed())
                .collect(Collectors.toMap(PromotionEntity::getFrontPromType, a -> a, (k1, k2) -> k1));
        ActivityPriority activityPriority = new ActivityPriority();
        activityPriority.setDeleteFlag(DeleteFlagEnum.UN_DELETE.getCode().longValue());
        List<ActivityPriority> activityPriorities = activityPriorityService.query(activityPriority);
        List<ActivityPriority> sortedActivityPriorities = activityPriorities.stream().sorted(Comparator.comparing(ActivityPriority::getSort)).collect(Collectors.toList());
        for (ActivityPriority sortedActivityPriority : sortedActivityPriorities) {
            if(promotionEntityMap.containsKey(sortedActivityPriority.getFrontPromotionType())){
                promotionEntity = promotionEntityMap.get(sortedActivityPriority.getFrontPromotionType());
                break;
            }
        }
        log.info("processPriority param = {}, result = {}", JSONObject.toJSONString(promotions), JSONObject.toJSONString(promotionEntity));
        return promotionEntity == null ? promotions.get(0) : promotionEntity;
    }
}
